﻿using System;
using GammaJul.ReSharper.GammaXaml.QuickFixes.Xaml;
using JetBrains.Annotations;
using JetBrains.ReSharper.Feature.Services.Bulbs;
using JetBrains.ReSharper.Feature.Services.Xaml.Bulbs;
using JetBrains.ReSharper.Intentions.Extensibility;
using JetBrains.ReSharper.Intentions.Extensibility.Menu;
using JetBrains.ReSharper.Psi.Xaml.Tree;
using JetBrains.Util;

namespace GammaJul.ReSharper.GammaXaml.ContextActions.Xaml {

	/// <summary>
	/// A context action that transforms a XAML <c>{RelativeSource}</c> markup extension into a <c>{x:Static}</c> one
	/// to reduce memory usage by reusing the same object.
	/// </summary>
	/// <remarks>Only available for WPF since Silverlight doesn't provide those static properties.</remarks>
	[ContextAction(Name = "Transform RelativeSource to x:Static", Group = "XAML", Description = "Transforms a XAML RelativeSource into a x:Static one.")]
	public class RelativeSourceToXStaticAction : RelativeSourceToXStaticActionBase, IContextAction {
		private readonly XamlContextActionDataProvider _provider;

		/// <summary>
		/// Finds the <see cref="IRelativeSourceUsage"/> that this action uses.
		/// </summary>
		/// <returns>A <see cref="IRelativeSourceUsage"/> implementation, or <c>null</c>.</returns>
		protected override IRelativeSourceUsage GetRelativeSource() {
			return _provider.FindNodeAtCaret<IRelativeSourceUsage>();
		}

		public void CreateBulbItems(BulbMenu menu) {
			menu.ArrangeContextAction(this);
		}

		public bool IsAvailable(IUserDataHolder cache) {
			// not available if there's already a corresponding quick fix or we're not on a x:Static RelativeSource node
			return cache.GetData(UseXStaticFix.InstanceKey) == null
				&& IsAvailable(GetRelativeSource());
		}

		public RelativeSourceToXStaticAction([NotNull] XamlContextActionDataProvider provider) {
			if (provider == null)
				throw new ArgumentNullException("provider");
			_provider = provider;
		}
	}

}